﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace PDX
{
    /// <summary>
    /// A single source for property change events for a given viewmodel.
    /// </summary>
    /// <remarks>
    /// The NotificationManager does two things.
    /// First, it listens for INPC on the viewmodel and lets the property
    /// models know (if a "transaction" is not already active).
    /// Second, if a value update is coming via a property model, it can
    /// begin a transaction, ignore all INPC (if any), and then notify
    /// the property models when the transaction is done.
    /// This can reduce or eliminate the need for INPC on viewmodels.
    /// </remarks>
    public class NotificationManager : INotifyPropertyChanged
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="NotificationManager"/> class.
        /// </summary>
        /// <param name="viewmodel">The viewmodel.</param>
        public NotificationManager(object viewmodel)
        {
            var inpc = viewmodel as INotifyPropertyChanged;
            if (inpc != null)
            {
                inpc.PropertyChanged += inpc_PropertyChanged;
            }
        }

        bool listening = true;
        void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (listening)
            {
                Notify();
            }
        }

        PropertyChangedEventArgs args = new PropertyChangedEventArgs("dummy");

        /// <summary>
        /// Begins a "property changed" transaction.
        /// </summary>
        public void BeginTransaction()
        {
            listening = false;
        }

        /// <summary>
        /// Ends the "property changed" transaction.
        /// </summary>
        public void EndTransaction()
        {
            Notify();

            listening = true;
        }

        void Notify()
        {
            var temp = PropertyChanged;
            if (temp != null)
            {
                temp(this, args);
            }
        }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
    }
}
